package com.ziq.zcamp.post

import androidx.lifecycle.ViewModel
import com.ziq.base.extension.launchWithTryAsynchronous
import com.ziq.zcamp.api.request.post.PostingCreateParam
import com.ziq.zcamp.api.respond.CampBaseRespond
import com.ziq.zcamp.api.respond.common.UploadFileRespond
import com.ziq.zcamp.api.service.CommonService
import com.ziq.zcamp.api.service.PostingService
import com.ziq.zcamp.api.service.request
import com.ziq.zcamp.bean.place.CampListItem
import com.ziq.zcamp.bean.place.LocationInfo
import com.ziq.zcamp.bean.post.ImageInfo
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
import java.util.*
import javax.inject.Inject

@HiltViewModel
class PublishDynamicViewModel @Inject constructor() : ViewModel() {

    @Inject
    lateinit var mPostingService: PostingService

    @Inject
    lateinit var mCommonService: CommonService

    fun sendPosting(title: String?, content: String?, imgList: List<ImageInfo>, location: LocationInfo?, campInfo: CampListItem?, startDate:Date?, endDate:Date?,
                    topicsList:List<String>,
                    onSuccess: ((result: CampBaseRespond) -> Unit)? = {},
                    onFail: ((result: String) -> Unit)? = {}) {

        launchWithTryAsynchronous (whenTry = {
            val param = PostingCreateParam()
            param.p_type = 1
            param.title = title
            param.content = content
            param.req_images = imgList
            param.location_addr = location?.site
            param.longitude = location?.longitude
            param.latitude = location?.latitude
            param.camp_id = campInfo?.id
            if (topicsList.isNotEmpty()){
                param.req_topic_names = topicsList
            }
            if(startDate != null){
                param.camping_start_time = startDate.time/1000
                if(endDate != null){
                    param.camping_end_time = endDate.time/1000
                } else {
                    param.camping_end_time = startDate.time/1000
                }
            }
            if(campInfo?.latitude?.isNotEmpty() == true && campInfo.longitude?.isNotEmpty() == true){
                param.location_addr = campInfo.location_addr
                param.longitude = campInfo.longitude?:""
                param.latitude = campInfo.latitude?:""
            }

            val response = mPostingService.postCreate(param).request()
            withContext(Dispatchers.Main){
                onSuccess?.invoke(response)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                onFail?.invoke("${it.message}")
            }
        })
    }

    fun uploadMultiImage(filePaths : List<String>,
                         onProgress: ((progress: Float) -> Unit)? = {},
                         onFinished: ((respondList: List<UploadFileRespond>) -> Unit)? = {}){
        val length = filePaths.size
        var index = -1
        val respondList = mutableListOf<UploadFileRespond>()
        fun callback(){
            index++
            if(index < length){
                upLoadPhoto(filePaths[index], onFinished = { respond ->
                    if(respond != null){
                        respond.index = index
                        respondList.add(respond)
                        onProgress?.invoke((index + 1) / (length * 1.0f))
                        callback()
                    } else {
                        respondList.add(UploadFileRespond())
                        onProgress?.invoke(1.0f)
                        onFinished?.invoke(respondList)
                    }
                })
            } else {
                onProgress?.invoke(1.0f)
                onFinished?.invoke(respondList)
            }
        }
        callback()
    }


    fun upLoadPhoto(filePath : String, onFinished: ((respond: UploadFileRespond?) -> Unit)? = {}){
        launchWithTryAsynchronous (whenTry = {
            val file = File(filePath)
            val requestFile = file.asRequestBody("multipart/form-data".toMediaTypeOrNull());
            val body = MultipartBody.Part.createFormData("file", file.name, requestFile);
            val response = mCommonService.uploadFile(body).request()
            withContext(Dispatchers.Main){
                onFinished?.invoke(response)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                onFinished?.invoke(null)
            }
        })
    }

    /**
     * 获取文件的类型
     */
    private fun obtainFileType(path:String):String{
        val lastDot: Int = path.lastIndexOf(".")
        return when(if (lastDot < 0 ) "" else path.substring(lastDot + 1).toLowerCase(Locale.ROOT)){
            "jpg" -> "jpg"
            "jpeg" -> "jpg"
            "png" -> "png"
            "gif" -> "gif"
            else -> {
                throw NullPointerException("不支持的文件格式")
            }
        }
    }

}